package com.gitee.faster.webdav.kernel;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.text.StrPool;
import com.gitee.faster.webdav.common.constant.Constants;
import com.gitee.faster.webdav.common.helper.JsonHelper;
import com.gitee.faster.webdav.logger.LoggerLevel;
import lombok.Data;
import lombok.experimental.Accessors;
import org.slf4j.Logger;

import java.io.File;

/**
 * @author hongda.li
 */
@Data
@Accessors(chain = true)
public final class Configuration {
    /**
     * 单例实例
     */
    private static final Configuration CONFIGURATION = new Configuration();

    /**
     * 默认日志级别
     */
    private LoggerLevel defaultLevel = LoggerLevel.DEBUG;

    /**
     * 日志存储路径
     */
    private String loggerPath = Constants.LOG_PATH;

    /**
     * WebDav 文件存储路径
     * 路径后缀不包含 /
     */
    private String storagePath = Constants.Config.USER_HOME;

    /**
     * 写入缓冲区默认大小 1KB
     */
    private int writeBufferSize = 1024;

    /**
     * 读取缓冲区默认大小 1KB
     */
    private int readBufferSize = 1024;

    /**
     * 主机地址
     */
    private String host = Constants.Config.LOCAL_HOST;

    /**
     * 端口号
     */
    private int port = 12345;

    /**
     * 最大检索深度
     */
    private int maxDepth = 3;

    /**
     * 账号
     */
    private String username = "manda";

    /**
     * 密码
     */
    private String password = "manda";

    /**
     * 输出配置信息
     *
     * @param logger 日志输出
     */
    public void show(Logger logger) {
        logger.info("主机地址 : {}", this.withReplacedHost());
        logger.info("端口地址 : {}", this.port);
        logger.info("存储地址 : {}", this.withReplacedStoragePath());
        logger.info("日志地址 : {}", this.loggerPath);
        logger.info("日志级别 : {}", this.defaultLevel);
        if (this.username != null && this.password != null) {
            logger.info("用户密码 : [{} : {}]", this.username, this.password);
        }
        logger.info("访问地址 : {}", this.httpPathBuilder().build());
    }

    /**
     * 将占位符替换为具体值后的主机地址
     *
     * @return 主机地址
     */
    public String withReplacedHost() {
        return this.host == null
                ? NetUtil.getLocalhostStr()
                : this.host.replace(Constants.Config.LOCAL_HOST, NetUtil.getLocalhostStr());
    }

    /**
     * 将占位符替换为具体值后的存储路径
     *
     * @return 存储路径
     */
    public String withReplacedStoragePath() {
        return this.storagePath == null
                ? FileUtil.getUserHomePath()
                : this.storagePath.replace(Constants.Config.USER_HOME, FileUtil.getUserHomePath());
    }

    public synchronized void rewriteFromJson() {
        File config = new File(Constants.Config.CONFIG_JSON_NAME);
        if (!FileUtil.exist(config)) {
            return;
        }

        String jsonStr = new FileReader(config).readString();
        if (CharSequenceUtil.isBlank(jsonStr)) {
            return;
        }

        this.from(JsonHelper.fromJson(jsonStr, Configuration.class));
    }

    public void from(Configuration other) {
        if (other == null) {
            return;
        }
        this.host = other.host;
        this.port = other.port;
        this.username = other.username;
        this.password = other.password;
        this.loggerPath = other.loggerPath;
        this.storagePath = other.storagePath;
        this.defaultLevel = other.defaultLevel;
        this.readBufferSize = other.readBufferSize;
        this.writeBufferSize = other.writeBufferSize;
    }

    /**
     * 获取全局唯一实例
     *
     * @return 单例模式
     */
    public static Configuration getInstance() {
        return CONFIGURATION;
    }

    /**
     * 将主机地址和端口号转为标准 HTTP 地址
     *
     * @return HTTP 地址
     */
    public UrlBuilder httpPathBuilder() {
        return UrlBuilder.ofHttp(this.withReplacedHost()).setPort(this.port);
    }
}
